package com.hitemole.controller;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.hitemole.input.InputHandler;
import com.hitemole.levelObject.Moles;
import com.hitemole.levelObject.Moles.MOLE_STATE;
import com.hitemole.manager.GameManager;
import com.hitemole.manager.GameManager.GAME_STATES;
import com.hitemole.manager.GameManager.MULTIPLAYER_STATES;
import com.hitemole.network.Network.GameMessage;
import com.hitemole.network.ServerGame;

public class GameServerController {
	private GameManager world;
	private int multiplier;
	private float comboBarIndex;
	private int combo = 3;
	private int index = 1;
	private GAME_STATES tempStates = GAME_STATES.GAME_RESUME;
	Color fontColor;
	private float time = 5;

	public GameServerController(GameManager world) {
		this.world = world;
		this.multiplier = 1;
		fontColor = new Color(world.getDefaultBigFont().getColor());
		world.setMultiplayerState(MULTIPLAYER_STATES.GOODGUY);
	}

	public void update(float delta) {
		if (Gdx.input.getInputProcessor() == null) {
			Gdx.input.setInputProcessor(InputHandler.InputHandler);
		}
		switch (world.getMultiplayerState()) {
		case BADGUY:
			 doBadGuy(delta);
			break;
		case END:
			break;
		case GOODGUY:
			doGoodGuy(delta);
			break;
		default:
			break;

		}

	}

	public void doBadGuy(float delta) {
		switch (world.getGameState()) {
		case GAME_END:
			fontColor.a += 0.5f * delta;
			if (fontColor.a >= 1) {
				fontColor.a = 0;
				break;
			}
			world.getDefaultBigFont().setColor(fontColor);
			for (Moles mole : world.getMoles()) {
				mole.stateTime = 0;
				mole.setAnimationKey("empty");
			}
			break;
		case GAME_EXIT:
			world.setGameState(GAME_STATES.GAME_RESET);
			world.setMultiplayerState(MULTIPLAYER_STATES.BADGUY);
			// TODO : Must Save this score
			break;
		case GAME_RESUME:
			world.setGameState(tempStates);
			Gdx.input.setInputProcessor(null);
			break;
		case GAME_PAUSE:
			Gdx.input.setInputProcessor(world.getStageUI());
			break;
		case GAME_PROGRESS:
			world.getScores().update(delta);
			world.getHammer().update(delta);
			if (world.getHammer().getCurrentAnimation()
					.isAnimationFinished(world.getHammer().stateTime)) {
				world.getHammer().setDrawAnimation(false);
			}
			for (Moles mole : world.getMoles()) {
				mole.update(delta);
				switch (mole.getState()) {
				case EMPTY:
					break;
				case SHOW:
					mole.setTimeUntilHide(mole.getTimeUntilHide() - delta);
					if (mole.getTimeUntilHide() <= 0) {
						hideMole(mole);
					}
					break;
				default:
					break;

				}
			}
			if (world.getLives() == 0) {
				world.setGameState(GAME_STATES.GAME_END);
			}
			break;
		case GAME_START:
			fontColor.a -= 1.3f * delta;
			if (index < 0 && fontColor.a <= 0) {
				world.setGameState(GAME_STATES.GAME_PROGRESS);
				fontColor.a = 1;
				index = 1;
				world.countDown = GameManager.COUNTDOWN_STRING[2];
				break;
			}
			if (fontColor.a <= 0) {
				world.countDown = GameManager.COUNTDOWN_STRING[index--];
				fontColor.a = 1;
			}
			world.getDefaultBigFont().setColor(fontColor);
			break;
		case GAME_RESET:
			for (Moles mole : world.getMoles()) {
				mole.reset();
			}
			index = 1;
			combo = 3;
			multiplier = 1;
			comboBarIndex = 0;
			world.resetLives();
			world.getComboBar().setEnd((int) comboBarIndex, 100);
			world.getScores().resetScore();
			world.setGameState(GAME_STATES.GAME_START);
			break;
		default:
			break;
		}
		float ratioY = getValueAtRange(Gdx.graphics.getHeight(), 0,
				ServerGame.serverGame.getClient().height, 0);
		float ratioX = getValueAtRange(Gdx.graphics.getWidth(), 0,
				ServerGame.serverGame.getClient().width, 0);

		for (int i = 0; i < InputHandler.InputHandler.getUserInput().size(); i++) {
			Vector2 vect = InputHandler.InputHandler.getUserInput().get(i);
			showMole((int) vect.x, (int) vect.y);
			sendGameMessage(2, new Vector2(ratioX * vect.x, ratioY * vect.y));
			InputHandler.InputHandler.getUserInput().remove(i);
		}
		for (int i = 0; i < ServerGame.serverGame.getUserInput().size(); i++) {
			Vector2 vect = ServerGame.serverGame.getUserInput().get(i);
			sendGameMessage(1, vect);
			showHammer((int) (ratioX * vect.x), (int) (ratioY * vect.y),ratioX,ratioY);
			ServerGame.serverGame.getUserInput().remove(i);
		}
	}

	public void doGoodGuy(float delta) {
		switch (world.getGameState()) {
		case GAME_END:
			fontColor.a += 0.5f * delta;
			if (fontColor.a >= 1) {
				fontColor.a = 0;
				break;
			}
			world.getDefaultBigFont().setColor(fontColor);
			for (Moles mole : world.getMoles()) {
				mole.stateTime = 0;
				mole.setAnimationKey("empty");
			}
			time -= delta;
			if (time <= 0) {
				time = 5;
				world.setGameState(GAME_STATES.GAME_EXIT);
			}
			break;
		case GAME_EXIT:
			world.setGameState(GAME_STATES.GAME_RESET);
			world.setMultiplayerState(MULTIPLAYER_STATES.BADGUY);
			// TODO : Must Save this score
			break;
		case GAME_RESUME:
			world.setGameState(tempStates);
			Gdx.input.setInputProcessor(null);
			break;
		case GAME_PAUSE:
			Gdx.input.setInputProcessor(world.getStageUI());
			break;
		case GAME_PROGRESS:
			world.getScores().update(delta);
			world.getHammer().update(delta);
			if (world.getHammer().getCurrentAnimation()
					.isAnimationFinished(world.getHammer().stateTime)) {
				world.getHammer().setDrawAnimation(false);
			}
			for (Moles mole : world.getMoles()) {
				mole.update(delta);
				switch (mole.getState()) {
				case EMPTY:
					break;
				case SHOW:
					mole.setTimeUntilHide(mole.getTimeUntilHide() - delta);
					if (mole.getTimeUntilHide() <= 0) {
						hideMole(mole);
					}
					break;
				default:
					break;

				}
			}
			if (world.getLives() == 0) {
				world.setGameState(GAME_STATES.GAME_END);
			}
			break;
		case GAME_START:
			fontColor.a -= 1.3f * delta;
			if (index < 0 && fontColor.a <= 0) {
				world.setGameState(GAME_STATES.GAME_PROGRESS);
				fontColor.a = 1;
				index = 1;
				world.countDown = GameManager.COUNTDOWN_STRING[2];
				break;
			}
			if (fontColor.a <= 0) {
				world.countDown = GameManager.COUNTDOWN_STRING[index--];
				fontColor.a = 1;
			}
			world.getDefaultBigFont().setColor(fontColor);
			break;
		case GAME_RESET:
			for (Moles mole : world.getMoles()) {
				mole.reset();
			}
			index = 1;
			combo = 3;
			multiplier = 1;
			comboBarIndex = 0;
			world.resetLives();
			world.getComboBar().setEnd((int) comboBarIndex, 100);
			world.getScores().resetScore();
			world.setGameState(GAME_STATES.GAME_START);
			break;
		default:
			break;
		}
		float ratioY = getValueAtRange(
				ServerGame.serverGame.getClient().height, 0,
				Gdx.graphics.getHeight(), 0);
		float ratioX = getValueAtRange(ServerGame.serverGame.getClient().width,
				0, Gdx.graphics.getWidth(), 0);
		for (int i = 0; i < InputHandler.InputHandler.getUserInput().size(); i++) {
			Vector2 vect = InputHandler.InputHandler.getUserInput().get(i);
			sendGameMessage(1, new Vector2(ratioX * vect.x, ratioY * vect.y));
			showHammer((int) vect.x, (int) vect.y,ratioX,ratioY);
			InputHandler.InputHandler.getUserInput().remove(i);
		}
		for (int i = 0; i < ServerGame.serverGame.getUserInput().size(); i++) {
			Vector2 vect = ServerGame.serverGame.getUserInput().get(i);
			sendGameMessage(2, vect);
			showMole((int) (ratioX * vect.x), (int) (ratioY * vect.y));
			ServerGame.serverGame.getUserInput().remove(i);
		}
	}

	public void sendGameMessage(int id, Vector2 position) {
		GameMessage gm = new GameMessage();
		gm.id = id;
		gm.mouseClick = position;
		ServerGame.serverGame.sendToClient(gm);
	}

	public float getValueAtRange(float oldMax, float oldMin, float newMax,
			float newMin) {
		return (oldMax - oldMin) / (newMax - newMin);
	}

	private void showMole(int x, int y) {
		for (Moles mole : world.getMoles()) {
			// System.out.println(mole.getRelativeCollisionShape().x+" "+screenX);
			if (!mole.getRelativeCollisionShape().contains(x, y)) {
				continue;
			}
			if (!mole.isInteractable()) {
				showMole(mole);
			}
		}
	}

	public void showRandomMole() {
		int randomMole = MathUtils.random(world.getMoles().size() - 1);
		showMole(world.getMoles().get(randomMole));
	}

	private void showMole(Moles mole) {
		mole.setInteraction(true);
		mole.setState(MOLE_STATE.SHOW);
		mole.stateTime = 0;
		mole.setAnimationKey("full");
		mole.setTimeUntilHide(mole.getCurrentAnimation().animationDuration
				+ (0.5f + (1 / multiplier)));
		mole.getCurrentAnimation().setPlayMode(Animation.NORMAL);
	}

	private void hideMole(Moles mole) {
		mole.setInteraction(false);
		mole.setTimeUntilShow(5 - (multiplier) + MathUtils.random(12));
		mole.stateTime = 0;
		mole.setState(MOLE_STATE.EMPTY);
		mole.getCurrentAnimation().setPlayMode(Animation.REVERSED);
	}

	// public void touched(int screenX, int screenY) {
	//
	// if (world.getGameState().equals(GAME_STATES.GAME_END)) {
	// world.setGameState(GAME_STATES.GAME_EXIT);
	// return;
	// }
	// if (world.getPauseButton().getRelativeCollisionShape()
	// .contains(screenX, screenY)) {
	// pause();
	// return;
	// }
	// if (world.getGameState().equals(GAME_STATES.GAME_PAUSE)
	// || world.getGameState().equals(GAME_STATES.GAME_START)) {
	// return;
	// }
	// }

	public void showHammer(int screenX, int screenY, float ratioX, float ratioY) {
		for (Moles mole : world.getMoles()) {
			// System.out.println(mole.getRelativeCollisionShape().x+" "+screenX);
			if (!mole.getRelativeCollisionShape().contains(screenX, screenY)) {
				continue;
			}
			if (mole.isInteractable()) {
				combo--;
				hideMole(mole);
				if (combo < 0 && combo <= 8) {
					multiplier += 1;
					combo = multiplier * 3;
				}
				world.getScores().addScore(10);
				world.getScores().setMultiplier(multiplier);
				comboBarIndex = (float) ((multiplier * 3) - combo)
						/ (multiplier * 3) * 100;
				world.getComboBar().setEnd((int) comboBarIndex, 100);
				sendGameMessage(3, new Vector2(screenX*ratioX,screenY*ratioY));
			} else {
				combo = 3;
				world.getScores().setMultiplier(1);
				multiplier = 1;
				comboBarIndex = 0;
				world.getComboBar().setEnd((int) comboBarIndex, 100);
				world.decreaseLives();
				sendGameMessage(4, new Vector2(screenX*ratioX,screenY*ratioY));
			}
		}
		world.getHammer().setRelativePosition(
				new Vector2(screenX - (35 * world.getHammer().xScale), screenY
						- (115 * world.getHammer().yScale)));
		world.getHammer().setDrawAnimation(true);
		world.getHammer().stateTime = 0;
	}

	public void pause() {
		if (!world.getGameState().equals(GAME_STATES.GAME_PAUSE))
			tempStates = world.getGameState();
		world.setGameState(GAME_STATES.GAME_PAUSE);
	}
}
